﻿using DoNet.Common.Encrypt;
using DoNet.Common.Extensions;
using DoNet.Common.Result;
using System.Collections.Specialized;
using System.Text;

namespace DoNet.Common.Helpers
{
    /// <summary>
    /// 签名验证自定义类
    /// </summary>
    public class SignHelper
    {
        /// <summary>
        /// 全局过滤器验证签名
        /// </summary>
        /// <param name="httpContext"></param>
        /// <returns></returns>
        public static CommonResult CheckSign(string appId, string appSecret, string nonce, long timeStamp, string signature, string data)
        {
            CommonResult result = new CommonResult();
            //判断timespan是否有效，请求是否超时
            DateTime tonow = timeStamp.UnixTimeToDateTime();
            var expires_minute = tonow.Minute - DateTime.Now.Minute;
            if (expires_minute >= -2 && expires_minute <= 2)
            {
                TimeSpan expiresSliding = DateTime.Now.AddMinutes(120) - DateTime.Now;
                bool blValidate = Validate(timeStamp.ToString(), nonce, appSecret, data, signature);
                if (!blValidate)
                {
                    result.ErrCode = "40004";
                    result.ErrMsg = "无效签名";
                }
                else
                {
                    result.ErrCode = "0";
                    result.Success = true;
                }
            }
            else
            {
                result.ErrCode = "50004";
                result.ErrMsg = "接口请求超时";
            }
            return result;
        }
        /// <summary>
        /// get请求查询参数， url上直接接参数时,通过此方法获取
        /// </summary>
        /// <param name="form">请求参数</param>
        /// <returns></returns>
        public static string GetQueryString(NameValueCollection form)
        {
            //第一步：取出所有get参数
            Dictionary<string, string> parames = new Dictionary<string, string>();
            if (form != null)
            {
                for (int f = 0; f < form.Count; f++)
                {
                    var key = form.Keys[f];
                    if (key != null)
                    {
                        var value = form[key];
                        if (!string.IsNullOrWhiteSpace(value))
                            parames.Add(key, value);
                    }
                }
            }
            // 第二步：把字典按Key的字母顺序排序
            IDictionary<string, string> sortedParams = new SortedDictionary<string, string>(parames);
            IEnumerator<KeyValuePair<string, string>> dem = sortedParams.GetEnumerator();

            // 第三步：把所有参数名和参数值串在一起
            StringBuilder query = new StringBuilder("");  //签名字符串
            if (parames == null || parames.Count == 0) return query.ToString();
            while (dem.MoveNext())
            {
                string key = dem.Current.Key;
                string value = dem.Current.Value;
                if (!string.IsNullOrEmpty(key)) query.Append(key).Append(value);
            }
            return query.ToString();
        }
        /// <summary>
        /// 签名验证
        /// </summary>
        /// <param name="timeStamp">时间戳</param>
        /// <param name="nonce">随机字符串</param>
        /// <param name="appSecret">客户端应用密钥</param>
        /// <param name="data">接口参数内容</param>
        /// <param name="signature">当前请求内容的数字签名</param>
        /// <returns></returns>
        public static bool Validate(string timeStamp, string nonce, string appSecret, string data, string signature)
        {
            var signStr = timeStamp + nonce + data + appSecret;
            string signMd5 = MD5Util.GetMD5_32(signStr);
            return signMd5 == signature;
        }

        /// <summary>
        /// 验证appId是否被允许
        /// </summary>
        /// <param name="appId"></param>
        /// <returns></returns>
        //private static AllowCacheApp VerifyAppId(string appId)
        //{
        //    AllowCacheApp allowCacheApp = new AllowCacheApp();
        //    if (string.IsNullOrEmpty(appId)) return allowCacheApp;
        //    YuebonCacheHelper yuebonCacheHelper = new YuebonCacheHelper();
        //    List<AllowCacheApp> list = yuebonCacheHelper.Get<object>(CacheConst.KeyAppList).ToJson().ToList<AllowCacheApp>();
        //    if (list != null && list.Count > 0)
        //    {
        //        allowCacheApp = list.Where(s => s.AppId == appId).FirstOrDefault();
        //    }
        //    return allowCacheApp;
        //}
    }
}
